package Zim::GUI::TrayIcon;

use strict;
use Gtk2;
use Zim::GUI::Component;

our $VERSION = '0.20';
our @ISA = qw/Zim::GUI::Component/;

our $icon_class;
BEGIN {
	eval 'use Gtk2::StatusIcon';
	#$@ = 1; # Testing
	unless ($@) { $icon_class = 'Gtk2::StatusIcon' }
	else {
		#warn $@;
		eval 'use Gtk2::TrayIcon';
		if ($@) {
			#warn $@;
			die 'Could not load Gtk2::StatusIcon nor Gtk2::TrayIcon';
		}
		$icon_class = 'Gtk2::TrayIcon';
	}
	#warn "Using $icon_class for the tray icon\n";
}

=head1 NAME

Zim::GUI::TrayIcon - TrayIcon widget for zim

=head1 DESCRIPTION

This module adds an icon in the system tray for zim that implement
"minimise to tray". This way you can always have zim running in the
background.

The context menu for the tray icon lists all pages in the current
history stack.

To use this module you need either Gtk2::StatusIcon (gtk+ >= 2.10)
or Gtk2::TrayIcon (can be found on CPAN).

=head1 EXPORT

None by default.

=head1 METHODS

=over 4

=item C<new(app => PARENT)>

Simple constructor.

=cut

sub init {
	my $self = shift;

	($icon_class eq 'Gtk2::StatusIcon')
		? $self->_init_statusicon()
		: $self->_init_trayicon()   ;
	
	$self->{app}{hide_on_delete} = 1;
	$SIG{'USR1'} = sub { $self->toggle_hide_window };
}

sub _init_statusicon {
	# TODO test this
	my $self = shift;

	my $icon = Gtk2::StatusIcon->new_from_file($Zim::ICON);
	#my $icon = Gtk2::StatusIcon->new_from_icon_name('zim');
	$icon->set_tooltip($self->{app}{name});
	$icon->signal_connect_swapped(popup_menu => \&popup_menu, $self);
	$icon->signal(activate => \&toggle_hide_window, $self);
}

sub _init_trayicon {
	my $self = shift;

	my $icon= Gtk2::TrayIcon->new("Zim ($$)");
	my $box = Gtk2::EventBox->new;
	$box->set_visible_window(0);
	$box->set_above_child(1);
	# TODO make icon themeable - use iconfactory instead of iconset
	# see gtk+ reference for gtk_image_new_from_icon_set()
	my $iconset = Gtk2::IconSet->new_from_pixbuf($self->{app}->get_icon);
	my $image = Gtk2::Image->new_from_icon_set(
		$iconset, 'large-toolbar');
	$box->add($image);
	my $tooltips = Gtk2::Tooltips->new;
	$tooltips->set_tip($box, $self->{app}{name});
	$box->signal_connect_swapped(
		button_press_event => \&on_button_press_event, $self);
	$box->signal_connect_swapped(popup_menu => \&popup_menu, $self);
	$icon->add($box);
	$icon->show_all;
}

sub on_button_press_event {
	my ($self, $event) = @_;
	return unless $event->type eq 'button-press';
	if ($event->button == 1) {
		$self->toggle_hide_window;
	}
	elsif ($event->button == 3) {
		$self->popup_menu($event);
	}
	return 1;
}

=item C<toggle_hide_window()>

Hides the main window of zim if it was visible or unhides it if it
it was invisible.

=cut

sub toggle_hide_window {
	my $self = shift;
	my $window = $self->{app};
	if ($window->is_active) {
		@{$self->{app}{settings}}{'x', 'y'} = $window->get_position;
		$window->hide;
	}
	else {
		$window->present;
		$window->move(@{$self->{app}{settings}}{'x', 'y'});
	}
}

=item C<popup_menu(EVENT)>

Show a popup menu containing pages in the history and a "quit" button.
EVENT is optional.

=cut

sub popup_menu {
	my $self = shift;
	my $button = shift || 0;
	my $time = shift || 0;
	($button, $time) = ($button->button, $button->time)
		if ref $button; # button was event object

	my $menu = Gtk2::Menu->new();

	for (qw/Home Today/) {
		my $item = Gtk2::ImageMenuItem->new_with_label($_);
		$item->set_image(
			Gtk2::Image->new_from_stock('gtk-home', 'menu') )
			if $_ eq 'Home' ;
		my $sub = 'Go'.$_;
		$item->signal_connect(
			activate => \&on_popup_menu_activate,
			[$self->{app}, 's', $sub]  );
		$menu->add($item);
	}
	
	my $separator = Gtk2::SeparatorMenuItem->new();
	$menu->add($separator);
	
	my $search_item = Gtk2::ImageMenuItem->new_with_label('Search');
	$search_item->signal_connect(activate =>
		sub { $self->{app}->SearchDialog->show } );
	$menu->add($search_item);

	$separator = Gtk2::SeparatorMenuItem->new();
	$menu->add($separator);
	
	my $hist = $self->{app}{history};
	my ($idx, @recent) = $hist ? $hist->get_recent : ();
	for (reverse 0 .. $#recent) {
		my $rec = $recent[$_];
		my $item = Gtk2::ImageMenuItem->new_with_label($rec->{basename});
		$item->set_image(
			Gtk2::Image->new_from_stock('gtk-yes', 'menu') )
			if $_ == $idx ;
		$item->signal_connect(
			activate => \&on_popup_menu_activate,
			[$self->{app}, 'r', $rec->{name}]  );
		$menu->add($item);
	}
	
	$separator = Gtk2::SeparatorMenuItem->new();
	$menu->add($separator);
	
	my $quit_item = Gtk2::ImageMenuItem->new_from_stock('gtk-quit');
	$quit_item->signal_connect(activate => sub {$self->{app}->Quit()} );
	$menu->add($quit_item);
	
	$menu->show_all;
	
	# TODO use Gtk2::StatusIcon::position_menu here
	$menu->popup(undef, undef, undef, undef, $button, $time);
}

sub on_popup_menu_activate {
	my ($app, $type, $page) = @{ pop(@_) };
	warn "app $app type $type page $page\n";
	$app->present;
	return $app->$page() unless $type eq 'r'; # GoHome or GoToday
	my $rec = $app->{history}->jump($page) || return;
	$app->load_page($rec);
}

1;

__END__

=back

=head1 AUTHOR

Jaap Karssenberg (Pardus) E<lt>pardus@cpan.orgE<gt>

Copyright (c) 2005 Jaap G Karssenberg. All rights reserved.
This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.

=head1 SEE ALSO

=cut

